// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using SixLabors.Fonts.Unicode;

namespace SixLabors.Fonts.Tables.AdvancedTypographic;

/// <summary>
/// Provides a map from Unicode <see cref="ScriptClass"/> to OTF <see cref="Tag"/>.
/// <see href="https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags"/>
/// </summary>
internal sealed class UnicodeScriptTagMap : Dictionary<ScriptClass, Tag[]>
{
    private static readonly Lazy<UnicodeScriptTagMap> Lazy = new(() => CreateMap());

    /// <summary>
    /// Prevents a default instance of the <see cref="UnicodeScriptTagMap"/> class from being created.
    /// </summary>
    private UnicodeScriptTagMap()
    {
    }

    public static UnicodeScriptTagMap Instance => Lazy.Value;

    // TODO: This map will likely require updating to add aliases for old fonts.
    // Use HarfBuzz as a reference.
    private static UnicodeScriptTagMap CreateMap()
        => new()
        {
            { ScriptClass.Unknown, new[] { Tag.Parse("zzzz") } },
            { ScriptClass.Common, new[] { Tag.Parse("zyyy") } },
            { ScriptClass.Inherited, new[] { Tag.Parse("zinh") } },
            { ScriptClass.Adlam, new[] { Tag.Parse("adlm") } },
            { ScriptClass.CaucasianAlbanian, new[] { Tag.Parse("aghb") } },
            { ScriptClass.Ahom, new[] { Tag.Parse("ahom") } },
            { ScriptClass.Arabic, new[] { Tag.Parse("arab") } },
            { ScriptClass.ImperialAramaic, new[] { Tag.Parse("armi") } },
            { ScriptClass.Armenian, new[] { Tag.Parse("armn") } },
            { ScriptClass.Avestan, new[] { Tag.Parse("avst") } },
            { ScriptClass.Balinese, new[] { Tag.Parse("bali") } },
            { ScriptClass.Bamum, new[] { Tag.Parse("bamu") } },
            { ScriptClass.BassaVah, new[] { Tag.Parse("bass") } },
            { ScriptClass.Batak, new[] { Tag.Parse("batk") } },
            { ScriptClass.Bengali, new[] { Tag.Parse("bng2"), Tag.Parse("beng") } },
            { ScriptClass.Bhaiksuki, new[] { Tag.Parse("bhks") } },
            { ScriptClass.Bopomofo, new[] { Tag.Parse("bopo") } },
            { ScriptClass.Brahmi, new[] { Tag.Parse("brah") } },
            { ScriptClass.Braille, new[] { Tag.Parse("brai") } },
            { ScriptClass.Buginese, new[] { Tag.Parse("bugi") } },
            { ScriptClass.Buhid, new[] { Tag.Parse("buhd") } },
            { ScriptClass.Chakma, new[] { Tag.Parse("cakm") } },
            { ScriptClass.CanadianAboriginal, new[] { Tag.Parse("cans") } },
            { ScriptClass.Carian, new[] { Tag.Parse("cari") } },
            { ScriptClass.Cham, new[] { Tag.Parse("cham") } },
            { ScriptClass.Cherokee, new[] { Tag.Parse("cher") } },
            { ScriptClass.Chorasmian, new[] { Tag.Parse("chrs") } },
            { ScriptClass.Coptic, new[] { Tag.Parse("copt") } },
            { ScriptClass.CyproMinoan, new[] { Tag.Parse("cpmn") } },
            { ScriptClass.Cypriot, new[] { Tag.Parse("cprt") } },
            { ScriptClass.Cyrillic, new[] { Tag.Parse("cyrl") } },
            { ScriptClass.Devanagari, new[] { Tag.Parse("dev2"), Tag.Parse("deva") } },
            { ScriptClass.DivesAkuru, new[] { Tag.Parse("diak") } },
            { ScriptClass.Dogra, new[] { Tag.Parse("dogr") } },
            { ScriptClass.Deseret, new[] { Tag.Parse("dsrt") } },
            { ScriptClass.Duployan, new[] { Tag.Parse("dupl") } },
            { ScriptClass.EgyptianHieroglyphs, new[] { Tag.Parse("egyp") } },
            { ScriptClass.Elbasan, new[] { Tag.Parse("elba") } },
            { ScriptClass.Elymaic, new[] { Tag.Parse("elym") } },
            { ScriptClass.Ethiopic, new[] { Tag.Parse("ethi") } },
            { ScriptClass.Georgian, new[] { Tag.Parse("geor") } },
            { ScriptClass.Glagolitic, new[] { Tag.Parse("glag") } },
            { ScriptClass.GunjalaGondi, new[] { Tag.Parse("gong") } },
            { ScriptClass.MasaramGondi, new[] { Tag.Parse("gonm") } },
            { ScriptClass.Gothic, new[] { Tag.Parse("goth") } },
            { ScriptClass.Grantha, new[] { Tag.Parse("gran") } },
            { ScriptClass.Greek, new[] { Tag.Parse("grek") } },
            { ScriptClass.Gujarati, new[] { Tag.Parse("gjr2"), Tag.Parse("gujr") } },
            { ScriptClass.Gurmukhi, new[] { Tag.Parse("gur2"), Tag.Parse("guru") } },
            { ScriptClass.Hangul, new[] { Tag.Parse("hang") } },
            { ScriptClass.Han, new[] { Tag.Parse("hani") } },
            { ScriptClass.Hanunoo, new[] { Tag.Parse("hano") } },
            { ScriptClass.Hatran, new[] { Tag.Parse("hatr") } },
            { ScriptClass.Hebrew, new[] { Tag.Parse("hebr") } },
            { ScriptClass.Hiragana, new[] { Tag.Parse("hira") } },
            { ScriptClass.AnatolianHieroglyphs, new[] { Tag.Parse("hluw") } },
            { ScriptClass.PahawhHmong, new[] { Tag.Parse("hmng") } },
            { ScriptClass.NyiakengPuachueHmong, new[] { Tag.Parse("hmnp") } },
            { ScriptClass.KatakanaOrHiragana, new[] { Tag.Parse("hrkt") } },
            { ScriptClass.OldHungarian, new[] { Tag.Parse("hung") } },
            { ScriptClass.OldItalic, new[] { Tag.Parse("ital") } },
            { ScriptClass.Javanese, new[] { Tag.Parse("java") } },
            { ScriptClass.KayahLi, new[] { Tag.Parse("kali") } },
            { ScriptClass.Katakana, new[] { Tag.Parse("kana") } },
            { ScriptClass.Kharoshthi, new[] { Tag.Parse("khar") } },
            { ScriptClass.Khmer, new[] { Tag.Parse("khmr") } },
            { ScriptClass.Khojki, new[] { Tag.Parse("khoj") } },
            { ScriptClass.KhitanSmallScript, new[] { Tag.Parse("kits") } },
            { ScriptClass.Kannada, new[] { Tag.Parse("knd2"), Tag.Parse("knda") } },
            { ScriptClass.Kaithi, new[] { Tag.Parse("kthi") } },
            { ScriptClass.TaiTham, new[] { Tag.Parse("lana") } },
            { ScriptClass.Lao, new[] { Tag.Parse("laoo") } },
            { ScriptClass.Latin, new[] { Tag.Parse("latn") } },
            { ScriptClass.Lepcha, new[] { Tag.Parse("lepc") } },
            { ScriptClass.Limbu, new[] { Tag.Parse("limb") } },
            { ScriptClass.LinearA, new[] { Tag.Parse("lina") } },
            { ScriptClass.LinearB, new[] { Tag.Parse("linb") } },
            { ScriptClass.Lisu, new[] { Tag.Parse("lisu") } },
            { ScriptClass.Lycian, new[] { Tag.Parse("lyci") } },
            { ScriptClass.Lydian, new[] { Tag.Parse("lydi") } },
            { ScriptClass.Mahajani, new[] { Tag.Parse("mahj") } },
            { ScriptClass.Makasar, new[] { Tag.Parse("maka") } },
            { ScriptClass.Mandaic, new[] { Tag.Parse("mand") } },
            { ScriptClass.Manichaean, new[] { Tag.Parse("mani") } },
            { ScriptClass.Marchen, new[] { Tag.Parse("marc") } },
            { ScriptClass.Medefaidrin, new[] { Tag.Parse("medf") } },
            { ScriptClass.MendeKikakui, new[] { Tag.Parse("mend") } },
            { ScriptClass.MeroiticCursive, new[] { Tag.Parse("merc") } },
            { ScriptClass.MeroiticHieroglyphs, new[] { Tag.Parse("mero") } },
            { ScriptClass.Malayalam, new[] { Tag.Parse("mlm2"), Tag.Parse("mlym") } },
            { ScriptClass.Modi, new[] { Tag.Parse("modi") } },
            { ScriptClass.Mongolian, new[] { Tag.Parse("mong") } },
            { ScriptClass.Mro, new[] { Tag.Parse("mroo") } },
            { ScriptClass.MeeteiMayek, new[] { Tag.Parse("mtei") } },
            { ScriptClass.Multani, new[] { Tag.Parse("mult") } },
            { ScriptClass.Myanmar, new[] { Tag.Parse("mym2"), Tag.Parse("mymr") } },
            { ScriptClass.Nandinagari, new[] { Tag.Parse("nand") } },
            { ScriptClass.OldNorthArabian, new[] { Tag.Parse("narb") } },
            { ScriptClass.Nabataean, new[] { Tag.Parse("nbat") } },
            { ScriptClass.Newa, new[] { Tag.Parse("newa") } },
            { ScriptClass.Nko, new[] { Tag.Parse("nkoo") } },
            { ScriptClass.Nushu, new[] { Tag.Parse("nshu") } },
            { ScriptClass.Ogham, new[] { Tag.Parse("ogam") } },
            { ScriptClass.OlChiki, new[] { Tag.Parse("olck") } },
            { ScriptClass.OldTurkic, new[] { Tag.Parse("orkh") } },
            { ScriptClass.Oriya, new[] { Tag.Parse("ory2"), Tag.Parse("orya") } },
            { ScriptClass.Osage, new[] { Tag.Parse("osge") } },
            { ScriptClass.Osmanya, new[] { Tag.Parse("osma") } },
            { ScriptClass.OldUyghur, new[] { Tag.Parse("ougr") } },
            { ScriptClass.Palmyrene, new[] { Tag.Parse("palm") } },
            { ScriptClass.PauCinHau, new[] { Tag.Parse("pauc") } },
            { ScriptClass.OldPermic, new[] { Tag.Parse("perm") } },
            { ScriptClass.PhagsPa, new[] { Tag.Parse("phag") } },
            { ScriptClass.InscriptionalPahlavi, new[] { Tag.Parse("phli") } },
            { ScriptClass.PsalterPahlavi, new[] { Tag.Parse("phlp") } },
            { ScriptClass.Phoenician, new[] { Tag.Parse("phnx") } },
            { ScriptClass.Miao, new[] { Tag.Parse("plrd") } },
            { ScriptClass.InscriptionalParthian, new[] { Tag.Parse("prti") } },
            { ScriptClass.Rejang, new[] { Tag.Parse("rjng") } },
            { ScriptClass.HanifiRohingya, new[] { Tag.Parse("rohg") } },
            { ScriptClass.Runic, new[] { Tag.Parse("runr") } },
            { ScriptClass.Samaritan, new[] { Tag.Parse("samr") } },
            { ScriptClass.OldSouthArabian, new[] { Tag.Parse("sarb") } },
            { ScriptClass.Saurashtra, new[] { Tag.Parse("saur") } },
            { ScriptClass.SignWriting, new[] { Tag.Parse("sgnw") } },
            { ScriptClass.Shavian, new[] { Tag.Parse("shaw") } },
            { ScriptClass.Sharada, new[] { Tag.Parse("shrd") } },
            { ScriptClass.Siddham, new[] { Tag.Parse("sidd") } },
            { ScriptClass.Khudawadi, new[] { Tag.Parse("sind") } },
            { ScriptClass.Sinhala, new[] { Tag.Parse("sinh") } },
            { ScriptClass.Sogdian, new[] { Tag.Parse("sogd") } },
            { ScriptClass.OldSogdian, new[] { Tag.Parse("sogo") } },
            { ScriptClass.SoraSompeng, new[] { Tag.Parse("sora") } },
            { ScriptClass.Soyombo, new[] { Tag.Parse("soyo") } },
            { ScriptClass.Sundanese, new[] { Tag.Parse("sund") } },
            { ScriptClass.SylotiNagri, new[] { Tag.Parse("sylo") } },
            { ScriptClass.Syriac, new[] { Tag.Parse("syrc") } },
            { ScriptClass.Tagbanwa, new[] { Tag.Parse("tagb") } },
            { ScriptClass.Takri, new[] { Tag.Parse("takr") } },
            { ScriptClass.TaiLe, new[] { Tag.Parse("tale") } },
            { ScriptClass.NewTaiLue, new[] { Tag.Parse("talu") } },
            { ScriptClass.Tamil, new[] { Tag.Parse("tml2"), Tag.Parse("taml") } },
            { ScriptClass.Tangut, new[] { Tag.Parse("tang") } },
            { ScriptClass.TaiViet, new[] { Tag.Parse("tavt") } },
            { ScriptClass.Telugu, new[] { Tag.Parse("tel2"), Tag.Parse("telu") } },
            { ScriptClass.Tifinagh, new[] { Tag.Parse("tfng") } },
            { ScriptClass.Tagalog, new[] { Tag.Parse("tglg") } },
            { ScriptClass.Thaana, new[] { Tag.Parse("thaa") } },
            { ScriptClass.Thai, new[] { Tag.Parse("thai") } },
            { ScriptClass.Tibetan, new[] { Tag.Parse("tibt") } },
            { ScriptClass.Tirhuta, new[] { Tag.Parse("tirh") } },
            { ScriptClass.Tangsa, new[] { Tag.Parse("tnsa") } },
            { ScriptClass.Toto, new[] { Tag.Parse("toto") } },
            { ScriptClass.Ugaritic, new[] { Tag.Parse("ugar") } },
            { ScriptClass.Vai, new[] { Tag.Parse("vaii") } },
            { ScriptClass.Vithkuqi, new[] { Tag.Parse("vith") } },
            { ScriptClass.WarangCiti, new[] { Tag.Parse("wara") } },
            { ScriptClass.Wancho, new[] { Tag.Parse("wcho") } },
            { ScriptClass.OldPersian, new[] { Tag.Parse("xpeo") } },
            { ScriptClass.Cuneiform, new[] { Tag.Parse("xsux") } },
            { ScriptClass.Yezidi, new[] { Tag.Parse("yezi") } },
            { ScriptClass.Yi, new[] { Tag.Parse("yiii") } },
            { ScriptClass.ZanabazarSquare, new[] { Tag.Parse("zanb") } },
        };
}
